package com.rdc.jiajiadictionary.data.gettranslate;

import android.Manifest;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build;
import android.os.Environment;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;

import com.rdc.jiajiadictionary.bean.Part;
import com.rdc.jiajiadictionary.bean.Word;
import com.rdc.jiajiadictionary.database.DataBaseHelper;

import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.ls.LSOutput;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class TranslateModel implements com.rdc.jiajiadictionary.data.gettranslate.TranslateModelInterface {

    private Context context;
    private String text;
    private final String API = "http://dict-co.iciba.com/api/dictionary.php?type=json&key=1F9CA812CB18FFDFC95FC17E9C57A5E1&w=";
    private String savePath;


    public TranslateModel(Context context){
        this.context = context;
        savePath = context.getExternalFilesDir(null).getAbsolutePath();
    }

    /**
     * 将presenter传入的EditText输入内容进行网络请求翻译
     * @param input
     * @param getDataCallBack
     */
    @Override
    public void getTranslateData(String input,GetDataCallBack getDataCallBack){
        text = input;
        String url = API + input;
        get(url,getDataCallBack);
    }

    public interface GetDataCallBack {
        void onComplete(Word word);
        void onDataNotAvailable();
    }

    /**
     * 进行网络请求，对获取的内容解析并通过回调接口传给presenter
     * @param url
     * @param getDataCallBack
     */
    public void  get(String url,GetDataCallBack getDataCallBack){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {

            }
            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (response.isSuccessful()){
                    String result = response.body().string();
                    Word word = new Word();
                    word = parseJSONWithJSONObject(result);
                    addHistory(word);
                    //对未下载的音频进行下载
                    getDataCallBack.onComplete(word);

                }
            }
        });
    }
    /**
     * 判断该单词发音是否已下载
     * @param word
     * @return true已下载，false没下载
     */
    public boolean isDownload(Word word){
        File file;
        file = new File(savePath);
        if (!file.exists()) { //文件夹不存在
            // 创建文件夹
            file.mkdirs();

        }
        File[] files = file.listFiles();
        file = new File(savePath,word.getWord_name()+".mp3");
        for (int i = 0;i <files.length;i++){
            if (files[i].getName().equals(file.getName())){
                word.setDownloadPath(file.getPath());
                return true;
            }
        }
        return false;
    }

    /**
     * 下载回调接口
     */
    public interface DownloadCallBack{
        void onDownloadSuccess(String path);
        void onDownloadFailed();
    }
    /**
     * 判断单词音频是否已下载，没下载则对音频进行下载，保存下载文件存放路径
     * @param word
     */
    public void downloadAudio(Word word,DownloadCallBack downloadCallBack){
        if (! isDownload(word)){
            final String url = word.getPh_am_mp3();
            OkHttpClient okHttpClient = new OkHttpClient();
            Request request = new Request.Builder().url(url).build();
            Call call = okHttpClient.newCall(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(@NotNull Call call, @NotNull IOException e) {

                }

                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                    InputStream inputStream = null;
                    FileOutputStream fileOutputStream = null;
                    int length = 0;
                    File file;
                    byte[] bytes = new byte[1024];
                    inputStream = response.body().byteStream();
                    file = new File(savePath,word.getWord_name()+".mp3");
                    fileOutputStream = new FileOutputStream(file);
                    while ((length = inputStream.read(bytes)) != -1){
                        fileOutputStream.write(bytes, 0, length);
                    }
                    fileOutputStream.flush();
                    downloadCallBack.onDownloadSuccess(file.getPath());
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    if (fileOutputStream != null) {
                        fileOutputStream.close();
                    }
                }
            });
        }

    }
    /**
     * 解析json
     * @param result
     * @return
     */
    private Word parseJSONWithJSONObject(String result) {

        Word word = new Word();
        try {
            JSONObject jsonObject = new JSONObject(result);

            word.setWord_name(jsonObject.getString("word_name"));

            JSONObject inJsonObject;
            inJsonObject= jsonObject.getJSONObject("exchange");

            word.setWord_pl(getWordData(inJsonObject,"word_pl"));
            word.setWord_third(getWordData(inJsonObject,"word_third"));
            word.setWord_past(getWordData(inJsonObject,"word_past"));
            word.setWord_done(getWordData(inJsonObject,"word_done"));
            word.setWord_ing(getWordData(inJsonObject,"word_ing"));
            word.setWord_er(getWordData(inJsonObject,"word_er"));
            word.setWord_est(getWordData(inJsonObject,"word_est"));

            String s = null;
            if(word.getWord_pl() != null){
                s = "复数: "+word.getWord_pl();
            }
            if (word.getWord_third() != null){
                if (s == null){
                    s = "第三人称单数: " + word.getWord_third();
                }else{
                    s = s + "\n" + "第三人称单数: " + word.getWord_third();
                }
            }
            if (word.getWord_past() != null){
                if (s == null){
                    s = "过去式: " +word.getWord_past();
                }else {
                    s = s + "\n" + "过去式: " + word.getWord_past();

                }
            }
            if (word.getWord_done() != null){
                if (s == null){
                    s = "过去分词: " +word.getWord_done();
                }else{
                    s = s + "\n" + "过去分词: " + word.getWord_done();
                }
            }
            if (word.getWord_ing() != null) {
                if (s == null){
                    s =  "现在分词: " + word.getWord_ing();
                }else {
                    s = s + "\n" + "现在分词: " + word.getWord_ing();
                }
            }
            if (word.getWord_er()!= null){
                if (s == null){
                    s =  "比较级: " + word.getWord_er();
                }else {
                    s = s + "\n" + "比较级: " + word.getWord_er();
                }
            }
            if (word.getWord_est() != null){
                if (s == null){
                    s = "最高级: " + word.getWord_est();
                }else {
                    s = s + "\n" + "最高级: " + word.getWord_est();
                }
            }
            word.setExchange(s);

            JSONArray jsonArray;
            jsonArray = jsonObject.getJSONArray("symbols");
            inJsonObject = jsonArray.getJSONObject(0);
            word.setPh_en(inJsonObject.getString("ph_en"));
            word.setPh_am(inJsonObject.getString("ph_am"));
            word.setPh_en_mp3(inJsonObject.getString("ph_tts_mp3"));
            word.setPh_am_mp3(inJsonObject.getString("ph_am_mp3"));
            JSONArray inJsonArray;
            inJsonArray = inJsonObject.getJSONArray("parts");
            List<Part> parts = new ArrayList<Part>();
            for(int i = 0 ; i < inJsonArray.length() ; i++){
                Part part = new Part();
                inJsonObject = inJsonArray.getJSONObject(i);
                part.setmPart(inJsonObject.getString("part"));

                JSONArray inInJsonArray = inJsonObject.getJSONArray("means");
                String means = null;
                for(int j = 0 ; j < inInJsonArray.length() ; j++){
                    if (means == null){
                        means = inInJsonArray.getString(j);
                    }else {
                        means = (means + ";"+inInJsonArray.getString(j));
                    }
                }
                part.setMeans(means);
                parts.add(part);
            }
            word.setParts(parts);
            word.setPart(getStringFromParts(word));
            word.setExist(isExistInDatabase(word.getWord_name(),"notebook"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return word;
    }

    /**
     * 将单词的parts转成String
     * @param word
     * @return
     */
    public String getStringFromParts(Word word){
        String string = null;
        if(word.getParts()!=null){
            for (int i = 0;i<word.getParts().size();i++){
                String p = word.getParts().get(i).getmPart()+"  "+word.getParts().get(i).getMeans();
                if(string!=null){
                    string = string+"\n"+p;
                }else {
                    string = p;
                }
            }
        }
        return string;
    }

    /**
     * 获取json中的数据
     * @param jsonObject
     * @param value
     * @return
     */
    public String getWordData(JSONObject jsonObject,String value) {
        Object data = null;
        String string = null;
        try {
            data = jsonObject.get(value);
            if(data instanceof JSONArray){
                string = ((JSONArray) data).getString(0);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return string;
    }

    /**
     * 添加到历史搜索
     * @param word
     */
    public void addHistory(Word word){
        DataBaseHelper dataBaseHelper = new DataBaseHelper(context,"word.db",null,1);
        SQLiteDatabase database = dataBaseHelper.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        //判断是否已存在历史搜索中，有则将原来的删除
        if (word.getWord_name() != null) {
            if (isExistInDatabase(word.getWord_name(), "history")) {
                database.delete("history", "word_name= ? ", new String[]{word.getWord_name()});
            }
            contentValues.put("word_name",word.getWord_name());
        } else {
            if (isExistInDatabase(text,"history")) {
                database.delete("history", "word_name= ? ", new String[]{text});
            }
            contentValues.put("word_name",text);
        }
        contentValues.put("word_parts",word.getPart());
        database.insert("history",null,contentValues);
        database.close();
    }

    /**
     * 添加单词到生词本中
     * @param word
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void addWordIntoNotebookInDatabase(Word word) {

        if(context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
            Toast.makeText(context, "当前无法获取相关权限，无法下载离线音频", Toast.LENGTH_SHORT).show();
        } else {
            downloadAudio(word, new DownloadCallBack() {
                @Override
                public void onDownloadSuccess(String path) {
                    word.setDownloadPath(path);
                }

                @Override
                public void onDownloadFailed() {

                }
            });
        }

        DataBaseHelper dataBaseHelper = new DataBaseHelper(context,"word.db",null,1);
        SQLiteDatabase database = dataBaseHelper.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("word_name",word.getWord_name());
        contentValues.put("word_exchange",word.getExchange());
        contentValues.put("word_parts",word.getPart());
        contentValues.put("word_ph_am",word.getPh_am());
        contentValues.put("word_ph_en",word.getPh_en());
        contentValues.put("word_ph_am_mp3",word.getPh_am_mp3());
        contentValues.put("word_ph_en_mp3",word.getPh_en_mp3());
        contentValues.put("word_download",word.getDownloadPath());
        database.insert("notebook",null,contentValues);
        database.close();
    }

    /**
     * 从生词本中移除单词
     * @param word
     */
    @Override
    public void removeWordFromNotebookInDatabase(Word word) {
        DataBaseHelper dataBaseHelper = new DataBaseHelper(context,"word.db",null,1);
        SQLiteDatabase database = dataBaseHelper.getWritableDatabase();
        database.delete("notebook","word_name = ?",new String[]{word.getWord_name()});
        database.close();
    }

    /**
     * 判断是否存在数据库中
     * @param wordName
     * @param book
     * @return
     */
    @Override
    public boolean isExistInDatabase(String wordName,String book) {
        DataBaseHelper dataBaseHelper = new DataBaseHelper(context,"word.db",null,1);
        SQLiteDatabase database = dataBaseHelper.getWritableDatabase();
        Cursor cursor = database.query(book,new String[]{"word_name"},null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                if (wordName!=null){
                    if (wordName.equals(cursor.getString(cursor.getColumnIndexOrThrow("word_name")))){
                        return true;
                    }
                }

            }while (cursor.moveToNext());
        }
        return false;
    }


}
